package cn.getech.data.metadata.service.impl;

import cn.getech.data.development.constant.*;
import cn.getech.data.development.entity.ConfConnect;
import cn.getech.data.development.entity.TableRelationshipEntity;
import cn.getech.data.development.entity.permission.SysRoleDataPermission;
import cn.getech.data.development.entity.permission.SysRoleDataPermissionExample;
import cn.getech.data.development.mapper.permission.SysRoleDataPermissionMapper;
import cn.getech.data.development.service.ConfConnectService;
import cn.getech.data.development.service.DataPermissionService;
import cn.getech.data.development.service.TableRelationshipService;
import cn.getech.data.development.utils.DataPermissionUtil;
import cn.getech.data.intelligence.common.exception.RRException;
import cn.getech.data.intelligence.common.utils.NameValue;
import cn.getech.data.intelligence.common.utils.PageUtils;
import cn.getech.data.intelligence.common.utils.Query;
import cn.getech.data.intelligence.common.utils.R;
import cn.getech.data.metadata.constant.MetaTableTypeEnum;
import cn.getech.data.metadata.controller.module.ModuleUtils;
import cn.getech.data.metadata.entity.CollectionSystemModuleEntity;
import cn.getech.data.metadata.entity.CollectionTableOperateEntity;
import cn.getech.data.metadata.entity.CollectionTableUserNotifyEntity;
import cn.getech.data.metadata.entity.meta.CollectionTableField;
import cn.getech.data.metadata.entity.meta.CollectionTableInfo;
import cn.getech.data.metadata.entity.permission.CollectionTableFieldPermission;
import cn.getech.data.metadata.entity.permission.CollectionTablePermissionExt;
import cn.getech.data.metadata.mapper.*;
import cn.getech.data.metadata.model.dto.AddCollectionRelationDto;
import cn.getech.data.metadata.model.dto.NewBloodRelationshipEntity;
import cn.getech.data.metadata.model.req.collectiontableinfo.CollectiionTableInfoListReq;
import cn.getech.data.metadata.model.req.collectiontableinfo.CollectionTableInfoChangeNotifyReq;
import cn.getech.data.metadata.model.req.collectiontableinfo.CollectionTableInfoDeleteReq;
import cn.getech.data.metadata.model.req.collectiontableinfo.CollectionTableInfoUpdateReq;
import cn.getech.data.metadata.model.res.CollectionTableFieldRes;
import cn.getech.data.metadata.model.res.CollectionTableInfoListRes;
import cn.getech.data.metadata.model.res.CollectionTableInfoRes;
import cn.getech.data.metadata.model.res.CollectionTableOperateInner;
import cn.getech.data.metadata.model.res.collectiontablestatistics.RelationField;
import cn.getech.data.metadata.model.res.collectiontablestatistics.RelationTable;
import cn.getech.data.metadata.service.*;
import cn.getech.system.center.constant.DefConnectEnum;
import cn.getech.system.center.utils.ShiroUtils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CollectionTableInfoServiceImpl extends ServiceImpl<CollectionTableMapper, CollectionTableInfo> implements CollectionTableInfoService {
    @Autowired
    private CollectionTableOperateService collectionTableOperateService;
    @Autowired
    private DataPermissionService dataPermissionService;
    @Autowired
    private CollectionTableUserNotifyService collectionTableUserNotifyService;
    @Autowired
    private CollectionSystemModuleService collectionSystemModuleService;
    @Autowired
    private ConfConnectService confConnectService;
    @Autowired
    private TableRelationshipService tableRelationshipService;
    @Autowired
    private CollectionTableFieldMapper collectionTableFieldMapper;
    @Autowired
    private CollectionTableField2Mapper collectionTableField2Mapper;
    @Autowired
    private CollectionTaskLogMapper collectionTaskLogMapper;
    @Autowired
    private SysRoleDataPermissionMapper sysRoleDataPermissionMapper;
    @Autowired
    private CollectionTableField2Service collectionTableField2Service;
    @Value("${spring.kafka.bootstrap-servers:}")
    private String kafkaUrl;
    @Autowired
    private BloodRelationshipMapper bloodRelationshipMapper;

    @Autowired
    private CollectionBloodService collectionBloodService;

    @Override
    public R info(Integer id) {
        CollectionTableInfoRes res = baseMapper.info(id);
        if (res == null)
            throw new RRException("没有获取到该记录");
        baseMapper.updateViewCount(id);
        String size = getSize(res.getTotalSize());
        res.setTotalSizeStr(size);

        List<NameValue<Object>> list = new ArrayList<>();
        NameValue<Object> tableName = new NameValue<Object>();
        tableName.setName("表名称");
        tableName.setValue(res.getTableName());
        list.add(tableName);
        NameValue<Object> tableType = new NameValue<Object>();
        tableType.setName("表类型");
        //表所属
        NameValue<Object> tableOwn = new NameValue<Object>();
        tableOwn.setName("资产类目");
//        List<CollectionSystemModuleEntity> moduleList = collectionSystemModuleService.list();
//        tableOwn.setValue(ModuleUtils.getAllPath(moduleList, res.getOwnModule()));
        String categoryNames = baseMapper.searchTablecategoryNames(id);
        tableOwn.setValue(categoryNames);
        String type = "外部元数据";
        if (StoreTableType.OFFLINE.getCode().equals(res.getTableType())) {
            //表别名
            String aliasValue = "表别名";
            NameValue<Object> topic = new NameValue<Object>();
            topic.setName(aliasValue);
            topic.setValue(res.getTableAlias());
            list.add(topic);

            //表类型
            type = "离线元数据";
            tableType.setValue(type);
            list.add(tableType);

            list.add(tableOwn);

            //表描述
            NameValue<Object> taleDesc = new NameValue<Object>();
            taleDesc.setName("描述");
            taleDesc.setValue(res.getTableDesc());
            list.add(taleDesc);

            //数据库
            NameValue<Object> dbName = new NameValue<Object>();
            dbName.setName("数据库");
            dbName.setValue(res.getDbName());
            list.add(dbName);

            //主键
            NameValue<Object> primarykey = new NameValue<Object>();
            primarykey.setName("主键");
            QueryWrapper<CollectionTableField> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("table_id", res.getId());
            List<CollectionTableField> tableFieldList = collectionTableField2Service.list(queryWrapper);
            String keyStr = tableFieldList.stream().filter(e -> e.getPrimaryKey() != null && e.getPrimaryKey() == 1)
                    .map(CollectionTableField::getFieldName).collect(Collectors.joining(","));
            primarykey.setValue(keyStr);
            list.add(primarykey);

            //字段
            NameValue<Object> allField = new NameValue<Object>();
            allField.setName("字段");
            allField.setValue(res.getAllField());
            list.add(allField);

            //分区字段
            NameValue<Object> partitionField = new NameValue<Object>();
            partitionField.setName("分区字段");
            partitionField.setValue(res.getPartitionField());
            list.add(partitionField);

            //是否临时表
            NameValue<Object> tmpTable = new NameValue<Object>();
            tmpTable.setName("是否是临时表");
            tmpTable.setValue(res.getTempFlag() != null && 1 == res.getTempFlag().intValue() ? "是" : "否");
            list.add(tmpTable);

            //表数据总条数
            NameValue<Object> rowsNum = new NameValue<Object>();
            rowsNum.setName("表数据总条数");
            rowsNum.setValue(res.getRowsNum());
            list.add(rowsNum);

            //表大小
            NameValue<Object> totalSize = new NameValue<Object>();
            totalSize.setName("表大小");
            totalSize.setValue(size);
            list.add(totalSize);

            //首次录入时间
            NameValue<Object> createTime = new NameValue<Object>();
            createTime.setName("首次录入时间");
            createTime.setValue(res.getCreateTime());
            list.add(createTime);


            //上次修改时间
            NameValue<Object> updateTime = new NameValue<Object>();
            updateTime.setName("上次修改时间");
            updateTime.setValue(res.getUpdateTime());
            list.add(updateTime);

            //最近一次操作人
            NameValue<Object> username = new NameValue<Object>();
            username.setName("最近一次操作人");
            username.setValue(res.getUsername());
            list.add(username);

        } else if (StoreTableType.ONLINE.getCode().equals(res.getTableType())) {
            //实时内部表
            if (YesOrNoEnum.YES.getValue().equals(res.getRealType())) {
                /*//表别名
                String aliasValue = "表别名";
                NameValue<Object> topic = new NameValue<Object>();
                topic.setName(aliasValue);
                topic.setValue(res.getTableAlias());
                list.add(topic);*/

                //表类型
                type = "实时元数据(内部表)";
                tableType.setValue(type);
                list.add(tableType);

                list.add(tableOwn);
                //表描述
                NameValue<Object> taleDesc = new NameValue<Object>();
                taleDesc.setName("描述");
                taleDesc.setValue(res.getTableDesc());
                list.add(taleDesc);

                //内部kafka地址
                NameValue<Object> source = new NameValue<Object>();
                source.setName("内部kafka地址");
                source.setValue(kafkaUrl);
                list.add(source);

                //数据库
                NameValue<Object> dbName = new NameValue<Object>();
                dbName.setName("数据库");
                dbName.setValue(res.getDbName());
                list.add(dbName);

                //字段
                NameValue<Object> allField = new NameValue<Object>();
                allField.setName("字段");
                allField.setValue(res.getAllField());
                list.add(allField);

                //分区字段
                NameValue<Object> partitionField = new NameValue<Object>();
                partitionField.setName("分区字段");
                partitionField.setValue(res.getPartitionField());
                list.add(partitionField);


                //首次录入时间
                NameValue<Object> createTime = new NameValue<Object>();
                createTime.setName("首次录入时间");
                createTime.setValue(res.getCreateTime());
                list.add(createTime);


                //上次修改时间
                NameValue<Object> updateTime = new NameValue<Object>();
                updateTime.setName("上次修改时间");
                updateTime.setValue(res.getUpdateTime());
                list.add(updateTime);

                //最近一次操作人
                NameValue<Object> username = new NameValue<Object>();
                username.setName("最近一次操作人");
                username.setValue(res.getUsername());
                list.add(username);

            } else {
                //实时外部表
                //表别名
             /*   String aliasValue = "表别名";
                NameValue<Object> topic = new NameValue<Object>();
                topic.setName(aliasValue);
                topic.setValue(res.getTableAlias());
                list.add(topic);*/

                //表类型
                //实时外部表
                type = "实时元数据(外部表)";
                tableType.setValue(type);
                list.add(tableType);

                list.add(tableOwn);
                //表描述
                NameValue<Object> taleDesc = new NameValue<Object>();
                taleDesc.setName("描述");
                taleDesc.setValue(res.getTableDesc());
                list.add(taleDesc);

                //外部kafka地址
                NameValue<Object> source = new NameValue<Object>();
                source.setName("外部kafka地址");
                String kafkaUrlStr = "";
                ConfConnect confConnect = null;
                if (res.getSourceId() != null && res.getSourceId() > 0) {
                    confConnect = confConnectService.getById(res.getSourceId());
                    if (confConnect != null) {
                        if (StoreTableType.ONLINE.getCode().equals(res.getRealType())) {
                            kafkaUrlStr = confConnect.getKafkaUrl();
                        }
                    }
                }

                source.setValue(kafkaUrlStr);
                list.add(source);

                //数据库
                NameValue<Object> dbName = new NameValue<Object>();
                dbName.setName("数据库");
                dbName.setValue(res.getDbName());
                list.add(dbName);


                //字段
                NameValue<Object> allField = new NameValue<Object>();
                allField.setName("字段");
                allField.setValue(res.getAllField());
                list.add(allField);


                //分区字段
                NameValue<Object> partitionField = new NameValue<Object>();
                partitionField.setName("分区字段");
                partitionField.setValue(res.getPartitionField());
                list.add(partitionField);


                //首次录入时间
                NameValue<Object> createTime = new NameValue<Object>();
                createTime.setName("首次录入时间");
                createTime.setValue(res.getCreateTime());
                list.add(createTime);


                //上次修改时间
                NameValue<Object> updateTime = new NameValue<Object>();
                updateTime.setName("上次修改时间");
                updateTime.setValue(res.getUpdateTime());
                list.add(updateTime);

                //最近一次操作人
                NameValue<Object> username = new NameValue<Object>();
                username.setName("最近一次操作人");
                username.setValue(res.getUsername());
                list.add(username);

            }

        } else {
            //外部元数据
            //表别名
         /*   String aliasValue = "表别名";
            NameValue<Object> topic = new NameValue<Object>();
            topic.setName(aliasValue);
            topic.setValue(res.getTableAlias());
            list.add(topic);*/

            //表类型
            type = "外部元数据";
            tableType.setValue(type);
            list.add(tableType);
            list.add(tableOwn);
            //表描述
            NameValue<Object> taleDesc = new NameValue<Object>();
            taleDesc.setName("描述");
            taleDesc.setValue(res.getTableDesc());
            list.add(taleDesc);

            ConfConnect confConnect = null;
            String ownerValue = "";
            if (res.getSourceId() != null && res.getSourceId() > 0) {
                confConnect = confConnectService.getById(res.getSourceId());
                if (confConnect != null) {
                    if (StoreTableType.ONLINE.getCode().equals(res.getRealType())) {

                    } else {
                        NameValue<Object> source = new NameValue<Object>();
                        source.setName("数据源ip");
                        source.setValue(confConnect.getHost());
                        list.add(source);
                        NameValue<Object> port = new NameValue<Object>();
                        port.setName("端口");
                        port.setValue(confConnect.getPort());
                        list.add(port);
                    }
                    if (ConnectTypeEnum.Oracle.getCode().equals(confConnect.getTypeId())) {
                        ownerValue = baseMapper.selectTableOwner(id);
                    }
                }
            }

            //数据库
            NameValue<Object> dbName = new NameValue<Object>();
            dbName.setName("数据库");
            dbName.setValue(res.getDbName());
            list.add(dbName);
            if (StringUtils.isNotEmpty(ownerValue)) {
                NameValue<Object> owner = new NameValue<Object>();
                owner.setName("owner");
                owner.setValue(ownerValue);
                list.add(owner);
            }
            //主键
            NameValue<Object> primarykey = new NameValue<Object>();
            primarykey.setName("主键");
            QueryWrapper<CollectionTableField> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("table_id", res.getId());
            List<CollectionTableField> tableFieldList = collectionTableField2Service.list(queryWrapper);
            String keyStr = tableFieldList.stream().filter(e -> e.getPrimaryKey() != null && e.getPrimaryKey() == 1)
                    .map(CollectionTableField::getFieldName).collect(Collectors.joining(","));
            primarykey.setValue(keyStr);
            list.add(primarykey);

            //字段
            NameValue<Object> allField = new NameValue<Object>();
            allField.setName("字段");
            allField.setValue(res.getAllField());
            list.add(allField);

            //分区字段
            NameValue<Object> partitionField = new NameValue<Object>();
            partitionField.setName("分区字段");
            partitionField.setValue(res.getPartitionField());
            list.add(partitionField);

            //是否临时表
            NameValue<Object> tmpTable = new NameValue<Object>();
            tmpTable.setName("是否是临时表");
            tmpTable.setValue(res.getTempFlag() != null && 1 == res.getTempFlag().intValue() ? "是" : "否");
            list.add(tmpTable);

            //表数据总条数
            NameValue<Object> rowsNum = new NameValue<Object>();
            rowsNum.setName("表数据总条数");
            rowsNum.setValue(res.getRowsNum());
            list.add(rowsNum);

            //表大小
            NameValue<Object> totalSize = new NameValue<Object>();
            totalSize.setName("表大小");
            totalSize.setValue(size);
            list.add(totalSize);

            //首次录入时间
            NameValue<Object> createTime = new NameValue<Object>();
            createTime.setName("首次录入时间");
            createTime.setValue(res.getCreateTime());
            list.add(createTime);


            //上次修改时间
            NameValue<Object> updateTime = new NameValue<Object>();
            updateTime.setName("上次修改时间");
            updateTime.setValue(res.getUpdateTime());
            list.add(updateTime);

            //最近一次操作人
            NameValue<Object> username = new NameValue<Object>();
            username.setName("最近一次操作人");
            username.setValue(res.getUsername());
            list.add(username);
        }

        //设置编辑权限
        NameValue nameValue = getEditAuth(id, res.getTableInfoId(), res.getSourceId(), res.getTableType());
        list.add(nameValue);
        R r = R.okWithData(list);
        r.put("hotCount", res.getHotCount());
        return r;
    }


    private NameValue getEditAuth(Integer tableId, Integer tableInfoId, Integer sourceId, Integer tableType) {
        NameValue nameValue = new NameValue();
        try {
            nameValue.setName("EditPression");
            nameValue.setValue(1);
            Long userId = ShiroUtils.getUserId();
            if (!DataPermissionUtil.isAdmin(userId.intValue())) {
                List<Integer> ids = new ArrayList<>();
                if (tableType != null && tableType == 1) {
                    //离线表 返回的是离线表的表ID
                    Map<String, Object> req = new HashMap<>();
                    req.put("tableType", PermissionTypeEnum.STORE.getType());
                    req.put("userId", userId);
                    req.put("tableId", tableInfoId);
                    ids = collectionTableField2Mapper.metaEditPermission(req);

                    //拿对应的离线表ID做判断
                    if (ids.contains(tableInfoId)) {
                        nameValue.setValue(1);
                    } else {
                        nameValue.setValue(0);
                    }

                } else if (tableType != null && tableType == 2) {
                    if (sourceId != null && sourceId > 0) {
                        //实时外部表，看对应的数据源是否有权限
                        Map<String, Object> req = new HashMap<>();
                        req.put("tableType", PermissionTypeEnum.RESOURCE.getType());
                        req.put("userId", userId);
                        req.put("tableId", sourceId);
                        ids = collectionTableField2Mapper.metaEditPermission(req);
                        //拿数据源ID判断
                        if (ids.contains(sourceId)) {
                            nameValue.setValue(1);
                        } else {
                            nameValue.setValue(0);
                        }
                    } else {
                        //实时内部元数据,返回的是实时表ID
                        Map<String, Object> req = new HashMap<>();
                        req.put("tableType", PermissionTypeEnum.REAL_TABLE.getType());
                        req.put("userId", userId);
                        req.put("tableId", tableInfoId);
                        ids = collectionTableField2Mapper.metaEditPermission(req);

                        //拿对应的实时表ID判断
                        if (ids.contains(tableInfoId)) {
                            nameValue.setValue(1);
                        } else {
                            nameValue.setValue(0);
                        }
                    }

                } else {
                    //外部源元数据，拿元数据表ID判断
                    Map<String, Object> req = new HashMap<>();
                    req.put("tableType", PermissionTypeEnum.METADATA_MANAGEMENT.getType());
                    req.put("userId", userId);
                    req.put("tableId", tableId);
                    ids = collectionTableField2Mapper.metaEditPermission(req);
                    if (ids.contains(tableId)) {
                        nameValue.setValue(1);
                    } else {
                        nameValue.setValue(0);
                    }
                }

                if (CollectionUtils.isEmpty(ids)) {
                    ids.add(-1);
                }


            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return nameValue;
    }

    private String getSize(BigDecimal totalSize) {
        if (totalSize == null)
            return "";

        int gInt = 1024 * 1024 * 1024;
        int mbInt = 1024 * 1024;
        int kbInt = 1024;

        long totalSizeLong = totalSize.longValue();
        long g = totalSizeLong / gInt;
        long mb = (totalSizeLong - g * gInt) / mbInt;
        long kb = (totalSizeLong - g * gInt - mb * mbInt) / kbInt;
        long b = totalSizeLong - g * gInt - mb * mbInt - kb * kbInt;
        if (g > 0) {
            return totalSize.divide(new BigDecimal(gInt)).setScale(2, BigDecimal.ROUND_HALF_UP) + "GB";
        } else if (mb > 0) {
            return totalSize.divide(new BigDecimal(mbInt)).setScale(2, BigDecimal.ROUND_HALF_UP) + "MB";
        } else if (kb > 0) {
            return totalSize.divide(new BigDecimal(kbInt)).setScale(2, BigDecimal.ROUND_HALF_UP) + "KB";
        } else if (b > 0) {
            return b + "B";
        } else {
            return b + "B";
        }
    }

    @Override
    public PageUtils<CollectionTableInfoListRes> listBy(CollectiionTableInfoListReq req) {
        Map<String, Object> params = new HashMap<>();
        //所有用户都可以查询元数据
        Long userId = ShiroUtils.getUserId();
        params.put("userId", userId);
        //根据目录筛选元数据表
        List<Integer> collectionTableIds = null;
        List<Integer> categoryIdsList = new ArrayList<>();
        if (req.getCategoryIdsList() != null&&req.getCategoryIdsList().size()>0) {
            for(String categoryId:req.getCategoryIdsList()){
                categoryIdsList.add(Integer.valueOf(categoryId));
            }
            if(categoryIdsList.size()>0){
                collectionTableIds = baseMapper.selectCollectionTableIds(categoryIdsList);
            }
            if(collectionTableIds.size()==0){
                collectionTableIds.add(-1);
            }
        }
        //非超管权限查数据
        if (req.getOption() != null && !DataPermissionUtil.isAdmin(userId.intValue())) {
            List<Integer> ids = DataPermissionUtil.getDataIds(userId.intValue(),
                    PermissionTypeEnum.METADATA_MANAGEMENT.getType(),
                    req.getOption());
            if (CollectionUtils.isEmpty(ids)) {
                ids.add(-1);
            }
            if(collectionTableIds!=null){
                List<Integer> intersection = ids.stream().filter(collectionTableIds::contains).collect(Collectors.toList());
                params.put("ids", intersection);
            }else {
                params.put("ids", ids);
            }
            List<Integer> offIds = DataPermissionUtil.getDataIds(userId.intValue(),
                    PermissionTypeEnum.STORE.getType(),
                    req.getOption());
            if (CollectionUtils.isEmpty(offIds)) {
                offIds.add(-1);
            }
            if(collectionTableIds!=null){
                List<Integer> intersection = offIds.stream().filter(collectionTableIds::contains).collect(Collectors.toList());
                params.put("offIds", intersection);
            }else {
                params.put("offIds", offIds);//离线表的id
            }
            List<Integer> onlineIds = DataPermissionUtil.getDataIds(userId.intValue(),
                    PermissionTypeEnum.REAL_TABLE.getType(),
                    req.getOption());
            if (CollectionUtils.isEmpty(onlineIds)) {
                onlineIds.add(-1);
            }
            if(collectionTableIds!=null){
                List<Integer> intersection = onlineIds.stream().filter(collectionTableIds::contains).collect(Collectors.toList());
                params.put("onlineIds", intersection);
            }else {
                params.put("onlineIds", onlineIds);///实时表内部表
            }
            List<Integer> resourceIds = DataPermissionUtil.getDataIds(PermissionTypeEnum.RESOURCE.getType(),
                    req.getOption());
            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(resourceIds)) {
                resourceIds.add(-1);//无权限
            }
            params.put("sourceIds", resourceIds);//实时表的外部表
        }else{
            params.put("list", true);//列表查询
            if(collectionTableIds!=null){
                if(collectionTableIds.size()>0){
                    params.put("idsTemp", collectionTableIds);
                }
            }
        }
        Integer tenantId = ShiroUtils.getTenantId();
        params.put("tenantId", tenantId);
        if (StringUtils.isNotEmpty(req.getTableName()))
            params.put("tableName", req.getTableName());
        if (req.getOwnSystem() != null)
            params.put("ownSystem", req.getOwnSystem());
        if (req.getOwnModule() != null)
            params.put("ownModule", req.getOwnModule());
        if (req.getTableType() != null) {
            params.put("tableType", req.getTableType());
        }
        //最近修改时间时间
        if (req.getDate() != null) {
            params.put("updateTime", req.getDate());
        }
        //表状态
        if (req.getState() != null) {
            params.put("state", req.getState());
        }
        //录入方式
        if (req.getStyle() != null) {
            switch (req.getStyle()){
                case "manual":params.put("taskType", 0);break;
                case "auto":params.put("taskType", 1);break;
                case "interface":params.put("taskType", 2);break;
            }
        }
        //数据库的选择
        if (StrUtil.isNotBlank(req.getDataBase())) {
            params.put("database", req.getDataBase());
        }
        IPage<CollectionTableInfoListRes> page = baseMapper.listPage(new Page<>(req.getPage(),
                        req.getLimit()) , params);
        for(CollectionTableInfoListRes res:page.getRecords()){
            List<Integer> cateIdList = baseMapper.selectCategoryIds(res.getId());
            List<String> cateNameList = new ArrayList<>();
            List<String> cateIdStrList = new ArrayList<>();
            for(Integer cateId:cateIdList){
                cateIdStrList.add(cateId.toString());
            }
            if(cateIdList.size()>0){
                cateIdStrList = baseMapper.selectCategoryNames(cateIdList);
            }
            res.setCategoryIdsList(cateIdStrList);
            res.setCategoryNamesList(cateNameList);
        }
        return new PageUtils<>(page);
    }

    @Transactional
    @Override
    public void update(CollectionTableInfoUpdateReq req) {

        Long userId = ShiroUtils.getUserId();
        // 批量编辑
        if (CollectionUtils.isNotEmpty(req.getIds())) {
            for (Integer id : req.getIds()) {
                CollectionTableInfo old = baseMapper.selectById(id);
                updateModule(id, userId, req.getOwnModule(), old);
            }
            return;
        }
        //单个编辑
        CollectionTableInfo old = baseMapper.selectById(req.getId());
        if (old == null)
            throw new RRException("没有该记录");

        CollectionSystemModuleEntity moduleEntity = collectionSystemModuleService.getById(old.getOwnModule());
        if (!DataPermissionUtil.isAdmin(userId.intValue()) ) {
            // 离线表和是实时表  要走创建人权限
            if (old.getTableInfoId() != null && old.getTableInfoId() > 0 && !userId.equals(old.getCreateUser())) {
                if (old.getTableType().equals(1)) {
                    //判断对应的离线数仓是否有权限
                    boolean hasPermissionHive = dataPermissionService.checkDataPermission(old.getTableInfoId(),
                            PermissionTypeEnum.STORE.getType(), PermissionTypeEnum.UPDATE.getType());
                    if (!hasPermissionHive) {
                        throw new RRException("没有修改的权限");
                    }
                } else if (old.getTableType().equals(2)) {
                    if (old.getSourceId() != null && old.getSourceId() > 0) {
                        boolean hasPermissionHive = dataPermissionService.checkDataPermission(old.getSourceId(),
                                PermissionTypeEnum.RESOURCE.getType(), PermissionTypeEnum.UPDATE.getType());
                        if (!hasPermissionHive) {
                            throw new RRException("没有实时元数据对应的数据源的修改的权限");
                        }
                    } else {
                        //判断对应的离线数仓是否有权限
                        boolean hasPermissionHive = dataPermissionService.checkDataPermission(old.getTableInfoId(),
                                PermissionTypeEnum.REAL_TABLE.getType(), PermissionTypeEnum.UPDATE.getType());
                        if (!hasPermissionHive) {
                            throw new RRException("没有修改的权限");
                        }
                    }
                }
                // 外部数据元表不走创建人权限
            } else if (old.getTableType() == null || old.getTableType().equals(3)) {
                boolean hasPermission = dataPermissionService.checkDataPermission(req.getId(),
                        PermissionTypeEnum.METADATA_MANAGEMENT.getType(), PermissionTypeEnum.UPDATE.getType());
                if (!hasPermission) {
                    //没有编辑权限
                    throw new RRException("没有修改的权限");
                }
            }

        }
        updateModule(req.getId(), userId, req.getOwnModule(), old);
    }

    private void updateModule(Integer id, Long userId, Integer ownModule, CollectionTableInfo old) {

        List<CollectionTableInfo> isHave = baseMapper.selectList(
                new QueryWrapper<CollectionTableInfo>()
                        .ne("id", id)
                        .eq("db_name", old.getDbName())
                        .eq("table_name", old.getTableName())
                        .eq("own_module", ownModule)
                        .eq("delete_flag", 0)
                        .eq("table_type", 3)
        );
        if (CollectionUtils.isNotEmpty(isHave)) {
            throw new RRException("当前模块存在相同的表");
        }
        CollectionTableInfo collectionTableInfo = new CollectionTableInfo();
        collectionTableInfo.setId(id);
        collectionTableInfo.setOwnModule(ownModule);
        collectionTableInfo.setUpdateTableTime(new Date());
        collectionTableInfo.setUpdateUser(userId);
        baseMapper.updateById(collectionTableInfo);
        CollectionTableOperateInner operateInner = new CollectionTableOperateInner();
        operateInner.setOldOwnModule(old.getOwnModule());
        operateInner.setNewOwnModule(ownModule);
        //添加表属性操作审计
        CollectionTableOperateEntity operateEntity = new CollectionTableOperateEntity();
        operateEntity.setTableId(id);
        operateEntity.setOperateType(2); //1:表结构 2:表属性
        operateEntity.setOperateType1Res(0L);
        operateEntity.setOperateType2Res(JSONUtil.toJsonStr(operateInner));
        operateEntity.setUserId(userId);
        operateEntity.setOperateTime(new Date());
        collectionTableOperateService.save(operateEntity);
    }

    @Override
    public List<CollectionTableInfo> listPage(long offset, long limit) {
        Map<String, Object> params = new HashMap<>();
        params.put("offset", offset);
        params.put("limit", limit);
        return baseMapper.listAllPage(params);
    }

    @Override
    public void update(CollectionTableInfoChangeNotifyReq req) {
        CollectionTableInfo old = baseMapper.selectById(req.getId());
        if (old == null)
            throw new RRException("没有该记录");
        Long userId = ShiroUtils.getUserId();
        CollectionTableUserNotifyEntity oldNotifyEntity = collectionTableUserNotifyService.getOne(
                new QueryWrapper<CollectionTableUserNotifyEntity>()
                        .eq("table_id", req.getId())
                        .eq("user_id", userId)
        );
        if (oldNotifyEntity == null) {
            CollectionTableUserNotifyEntity notifyEntity = new CollectionTableUserNotifyEntity();
            notifyEntity.setTableId(req.getId());
            notifyEntity.setUserId(userId);
            notifyEntity.setCreatePer(userId);
            notifyEntity.setCreateTime(new Date());
            collectionTableUserNotifyService.saveOrUpdate(notifyEntity);
        } else {
            collectionTableUserNotifyService.removeById(oldNotifyEntity.getTunId());
        }
    }

    @Override
    public void delete(CollectionTableInfoDeleteReq req) {
        //批量删除
        if (CollectionUtils.isNotEmpty(req.getIds())) {
            CollectionTableInfo newTableInfo = new CollectionTableInfo();
            newTableInfo.setDeleteFlag(1);//删除 1 是,0 否
            baseMapper.update(newTableInfo, new QueryWrapper<CollectionTableInfo>().in("id", req.getIds()));
            bloodRelationshipMapper.delete(new QueryWrapper<TableRelationshipEntity>()
                    .in("source_coll_table_id", req.getIds()).or()
                    .in("relation_coll_table_id", req.getIds()));
            return;
        }
        CollectionTableInfo old = baseMapper.selectById(req.getId());
        if (old == null)
            throw new RRException("没有该记录");
        if (ObjectUtils.equals(old.getTaskType(), 1))//录入方式 0 手动采集 1自动采集
            throw new RRException("只有手动采集的表可以删除");

        boolean hasPermission = dataPermissionService.checkDataPermission(req.getId(), PermissionTypeEnum.METADATA_MANAGEMENT.getType(), PermissionTypeEnum.DELETE.getType());
        if (!hasPermission)
            throw new RRException("没有删除的权限");

        CollectionTableInfo newTableInfo = new CollectionTableInfo();
        newTableInfo.setId(req.getId());
        newTableInfo.setDeleteFlag(1);//删除 1 是,0 否
        baseMapper.updateById(newTableInfo);
        bloodRelationshipMapper.delete(new QueryWrapper<TableRelationshipEntity>()
                .eq("source_coll_table_id", req.getId()).or()
                .eq("relation_coll_table_id", req.getId()));
    }


    @Override
    public JSONObject getBloodRelationJSON(Integer id, Integer type, Integer flag) {
        CollectionTableInfo old = null;
        if (YesOrNoEnum.YES.getValue().equals(type)) {//离线表
            old = baseMapper.selectHiveTableById(id);
        } else {//元数据表
            old = baseMapper.selectById(id);   // 找collection_table_info表
        }
        collectionBloodService.synBloodData(old.getId());
        JSONObject data = new JSONObject();
        if (old != null) {
            QueryWrapper<TableRelationshipEntity> paramSource = new QueryWrapper<>();
            paramSource.eq("source_coll_table_id", old.getId());
            if (YesOrNoEnum.YES.getValue().equals(flag)) {//过滤自动血缘
                paramSource.eq("data_type",YesOrNoEnum.NO.getValue());
            }
            if (old.getTableInfoId() != null) {
                paramSource.or().eq("source_table_id", old.getTableInfoId())
                        .eq("data_type",YesOrNoEnum.NO.getValue());
            }
            List<TableRelationshipEntity> sourceList = tableRelationshipService.list(paramSource);  // 对表bdp_table_relationship查询
            // 获取当前表的字段信息
            List<CollectionTableFieldRes> collectionTableFieldRes = collectionTableField2Mapper.selectByTableId(id);
            data.put("currentCollectionTableField", collectionTableFieldRes);
            QueryWrapper<TableRelationshipEntity> paramResult = new QueryWrapper<>();
            paramResult.eq("relation_coll_table_id", old.getId());
            if (YesOrNoEnum.YES.getValue().equals(flag)) {//过滤手动
                paramResult.eq("data_type",YesOrNoEnum.NO.getValue());
            }
            List<TableRelationshipEntity> resultList = tableRelationshipService.list(paramResult);
            List<TableRelationshipEntity> allList=new ArrayList<>(sourceList);
            allList.addAll(resultList);
            Set<Integer> ids = new HashSet<>(allList.size());
            ids.add(old.getId());
            for (TableRelationshipEntity s : allList) {
                if (s.getRelationCollTableId() != null) {
                    ids.add(s.getRelationCollTableId());
                }
                if (s.getSourceCollTableId() != null) {
                    ids.add(s.getSourceCollTableId());
                }
                if (s.getSourceTableId() != null) {
                    ids.add(s.getSourceTableId());
                }
            }
            List<RelationTable> list = baseMapper.selectRelationTable(ids);
            Map<Integer,RelationTable> tableDbTypeMap=new HashMap<>();
            for (RelationTable relationTable : list) {
                tableDbTypeMap.put(relationTable.getTableId(), relationTable);
            }
            Map<Integer, List<TableRelationshipEntity>> sourceMap = sourceList.stream().filter(s -> s.getRelationCollTableId() != null)
                    .collect(Collectors.groupingBy(TableRelationshipEntity::getRelationCollTableId));
            List<RelationTable> sourceTables = Lists.newArrayList();
            for (Integer tableId : sourceMap.keySet()) {
                RelationTable table =new RelationTable().copyBean(tableDbTypeMap.get(tableId));
                table.setType(1);    // 上游表
                table.setTableId(tableId);
                //一个字段对应多个血缘字段
                Map<String, List<TableRelationshipEntity>> fieldMap = sourceMap.get(tableId).stream().collect(
                        Collectors.groupingBy(TableRelationshipEntity::getRelationFieldName));
                for (String fieldName : fieldMap.keySet()) {
                    RelationField field = new RelationField();
                    field.setFileName(fieldName);
                    for (TableRelationshipEntity source : fieldMap.get(fieldName)) {
                        field.getToIdList().add(source.getSourceTableName() + "_" + source.getSourceFieldName());  //下游表名+下游字段名
                        field.setToFiledName(source.getSourceFieldName());
                        field.setToTableName(source.getSourceTableName());
                        field.setType(1);
                        table.setIco(source.getDataType());
                        field.setIco(source.getDataType());
                        field.setTableName(source.getRelationTableName());
                        table.setTableName(source.getRelationTableName());
                        field.setUuid(source.getRelationTableName() + "_" + fieldName);    // 上游表名+上游字段
                    }
                    table.getFieldList().add(field);
                }
                sourceTables.add(table);
            }
            data.put("sourceList", sourceTables);


            List<RelationTable> resultTables = Lists.newArrayList();
            //离线数据配置血缘入口
            {
                Map<Integer, List<TableRelationshipEntity>> resultMap = resultList.stream().filter(s->s.getSourceTableId()!=null)
                        .collect(Collectors.groupingBy(TableRelationshipEntity::getSourceTableId));
                for (Integer tableId : resultMap.keySet()) {
                    CollectionTableInfo offTable = baseMapper.selectHiveTableById(tableId);
                    if (offTable == null) {
                        continue;
                    }
                    RelationTable table =new RelationTable().copyBean(tableDbTypeMap.get(offTable.getId()));
                    table.setTableId(offTable.getId());
                    //一个字段对应多个源头
                    Map<String, List<TableRelationshipEntity>> fieldMap = resultMap.get(tableId).stream().collect(
                            Collectors.groupingBy(TableRelationshipEntity::getSourceFieldName));
                    table.setType(0);   // 下游
                    for (String fieldName : fieldMap.keySet()) {
                        RelationField field = new RelationField();
                        field.setFileName(fieldName);
                        field.setUuid(tableId + "_" + fieldName);    // 上游表名+上游字段
                        for (TableRelationshipEntity source : fieldMap.get(fieldName)) {
                            field.getToIdList().add(source.getRelationTableName() + "_" + source.getRelationFieldName());  //上游表+字段
                            field.setToTableName(source.getRelationTableName());
                            field.setToFiledName(source.getRelationFieldName());
                            field.setToDbName(source.getRelationDbname());
                            field.setType(0);
                            table.setIco(source.getDataType());
                            field.setIco(source.getDataType());
                            field.setToSourceId(source.getRelationSourceId());
                            field.setTableName(source.getSourceTableName());
                            table.setTableName(source.getSourceTableName());
                            field.setUuid(source.getSourceTableName() + "_" + fieldName);    // 上游表名+上游字段
                        }
                        table.getFieldList().add(field);
                    }
                    resultTables.add(table);
                }
            }
            {
                Map<Integer, List<TableRelationshipEntity>> resultMap = resultList.stream().filter(s->s.getSourceCollTableId()!=null)
                        .collect(Collectors.groupingBy(TableRelationshipEntity::getSourceCollTableId));

                for (Integer tableId : resultMap.keySet()) {
                    RelationTable table =new RelationTable().copyBean(tableDbTypeMap.get(tableId));
                    table.setTableId(tableId);
                    //一个字段对应多个源头
                    Map<String, List<TableRelationshipEntity>> fieldMap = resultMap.get(tableId).stream().collect(
                            Collectors.groupingBy(TableRelationshipEntity::getSourceFieldName));
                    table.setType(0);   // 下游
                    for (String fieldName : fieldMap.keySet()) {
                        RelationField field = new RelationField();
                        field.setFileName(fieldName);
                        for (TableRelationshipEntity source : fieldMap.get(fieldName)) {
                            field.getToIdList().add(source.getRelationTableName() + "_" + source.getRelationFieldName());  //上游表+字段
                            field.setToTableName(source.getRelationTableName());
                            field.setToFiledName(source.getRelationFieldName());
                            field.setToDbName(source.getRelationDbname());
                            field.setToSourceId(source.getRelationSourceId());
                            field.setType(0);
                            table.setIco(source.getDataType());
                            field.setIco(source.getDataType());
                            field.setTableName(source.getSourceTableName());
                            table.setTableName(source.getSourceTableName());
                            field.setUuid(source.getSourceTableName() + "_" + fieldName);
                        }
                        table.getFieldList().add(field);
                    }
                    resultTables.add(table);
                }
            }

            if (CollectionUtils.isNotEmpty(resultTables)) {
                resultTables = resultTables.stream().collect(
                        Collectors.collectingAndThen(
                                Collectors.toCollection(() ->
                                        new TreeSet<>(Comparator.comparing(RelationTable::getTableId)
                                        )), ArrayList::new));

            }

            data.put("resultList", resultTables);
            RelationTable table =new RelationTable().copyBean(tableDbTypeMap.get(old.getId()));
            if (table == null) {
                table = new RelationTable();
            }
            table.setTableName(old.getTableName());
            table.setTableId(old.getId());
            Set<String> fieldNames = Sets.newHashSet();
            for (TableRelationshipEntity tableRelationshipEntity : sourceList) {
                fieldNames.add(tableRelationshipEntity.getSourceFieldName());
            }
            for (TableRelationshipEntity tableRelationshipEntity : resultList) {
                fieldNames.add(tableRelationshipEntity.getRelationFieldName());
            }
            for (String fieldName : fieldNames) {
                RelationField field = new RelationField();
                field.setFileName(fieldName);
                field.setUuid(old.getTableName() + "_" + fieldName);
                table.getFieldList().add(field);
            }
            data.put("currentTable", table);
        }
        return data;
    }

    // 获取当前表信息与数据源
    @Override
    public JSONObject getbloodParameterPlus(Integer id) {
        CollectionTableInfo old = null;
        old = baseMapper.selectById(id);// 找collection_table_info表
        JSONObject data = new JSONObject();
        if (old != null) {
            // 获取当前表的信息
            NewBloodRelationshipEntity bloodRelationCurrent = new NewBloodRelationshipEntity();
            // 获取当前表的source_id，得到数据源,数据名，表名,表id
            CollectionTableInfo collectionTableInfo = baseMapper.selectById(id);
//         bloodRelationCurrent.setBdpTableId(id);    // 表id
            bloodRelationCurrent.setDbName(collectionTableInfo.getDbName());   // 数据库名
            bloodRelationCurrent.setTableName(collectionTableInfo.getTableName());  // 表名

            Integer sourceId = collectionTableInfo.getSourceId();      // 获取数据源id
            bloodRelationCurrent.setSourceId(sourceId);               // 数据源id
            Map<String, Object> connectSource = collectionTaskLogMapper.getConnectSource(sourceId);
            if (connectSource != null && connectSource.get("name") != null) {
                bloodRelationCurrent.setSourceName((String) connectSource.get("name"));   // 获取数据源名称
            }
            // 获取当前表的字段信息
            Map<String, List<CollectionTableFieldRes>> FiedMapCurrent = new HashMap();
            List<CollectionTableFieldRes> collectionTableFieldCurrent = collectionTableField2Mapper.selectByTableId(id);
            if (collectionTableFieldCurrent != null) {
                FiedMapCurrent.put(collectionTableInfo.getTableName(), collectionTableFieldCurrent);
            }
            bloodRelationCurrent.setCollectionTableFieldResRelation(FiedMapCurrent);
            bloodRelationCurrent.setBdpTableId(baseMapper.selectBdpTableId(collectionTableInfo.getDbName(), collectionTableInfo.getTableName()));
            data.put("bloodRelationCurrent", bloodRelationCurrent);

        }

        // 获取所有数据源的信息
        List<HashMap<String, Object>> dateSource = avro.shaded.com.google.common.collect.Lists.newArrayList();
        dateSource.add(new HashMap<String, Object>() {{
            put("sourceId", DefConnectEnum.HIVE.getCode());
            put("sourceName", DefConnectEnum.HIVE.getName());
        }});
        dateSource.add(new HashMap<String, Object>() {{
            put("sourceId", DefConnectEnum.IMPALA.getCode());
            put("sourceName", DefConnectEnum.IMPALA.getName());
        }});
        dateSource.add(new HashMap<String, Object>() {{
            put("sourceId", DefConnectEnum.KAFKA.getCode());
            put("sourceName", DefConnectEnum.KAFKA.getName());
        }});
        dateSource.add(new HashMap<String, Object>() {{
            put("sourceId", DefConnectEnum.OTHER.getCode());
            put("sourceName", DefConnectEnum.OTHER.getName());
        }});
        List<Integer> typeIds = new ArrayList<>();
        ConnectTypeEnum[] values = ConnectTypeEnum.values();
        for (ConnectTypeEnum value : values) {
            if (value.getType().getCode() == ConTypeType.JDBC.getCode()) {
                typeIds.add(value.getCode());
            }
        }
        Integer tenantId = ShiroUtils.getTenantId();
        dateSource.addAll(collectionTaskLogMapper.getDateSource(typeIds,tenantId));
        data.put("dateSource", dateSource);
        return data;
    }




    // 获取数据源下的数据库
    @Override
    public List<String> getBloodParameterDbPlus(Map<String, Object> params) {

        //直接获取对应的数据源下的对应的库
        List<String> lists = new ArrayList<>();
        if (null != params && null != params.get("sourceId")) {
            Integer tenantId = ShiroUtils.getTenantId();
            params.put("tenantId", tenantId);
            int sourceId = Integer.parseInt(params.get("sourceId").toString());
            if (sourceId > 0 || sourceId == -1) {
                ConfConnect confConnect = confConnectService.getById(sourceId);
                if (null != confConnect) {
                    ConnectTypeEnum t = ConnectTypeEnum.ObjOf(confConnect.getTypeId());
                    String sourceConf = t.getUrl().replace("<host>", confConnect.getHost())
                            .replace("<port>", confConnect.getPort()).replace("<db_name>", "");
                    params.put("sourceConf", sourceConf);
                }
                return collectionTaskLogMapper.getDateSourceDb(params);
            } else {
                for (DBTypeEnum value : DBTypeEnum.values()) {
                    lists.add(value.getName());
                }
            }
        }
        return lists;
    }



    // 获取该数据源，数据库下的表   表的id：表名
    @Override
    public List<Map<String, Object>> getBloodParameterTablePlus(Map<String, Object> params) {
        //根据配置查询对应的配置
        if (null != params && null != params.get("sourceId")) {
            String stringSourceId = params.get("sourceId").toString();
            Integer tenantId = ShiroUtils.getTenantId();
            params.put("tenantId", tenantId);
            Integer sourceId = Integer.valueOf(stringSourceId);
            if (sourceId <= 0) {
                if (DefConnectEnum.HIVE.getCode().equals(sourceId)) {
                    params.put("sourceId", 0);
                    params.put("tableType", 1);//hive表
                    params.put("storeEngine", 1);
                }
                if (DefConnectEnum.OTHER.getCode().equals(sourceId)) {
                    params.put("sourceId", -1);
                    params.put("tableType", 3);//外部表
                }
                if (DefConnectEnum.IMPALA.getCode().equals(sourceId)) {
                    params.put("tableType", 1);//hive表
                    params.put("sourceId", 0);
                }
                if (DefConnectEnum.KAFKA.getCode().equals(sourceId)) {
                    params.put("sourceId", 0);
                    params.put("tableType", 2);
                }
                List<Map<String, Object>> lists = baseMapper.selectTableBysourceAndDb(params);
                return lists;
            } else {
                //拼装成ipconif 进行查询
                ConfConnect confConnect = confConnectService.getById(sourceId);
                if (null != confConnect) {
                    String dbName = "";
                    if (null != params.get("dbName")) {
                        dbName = params.get("dbName").toString();
                    }
                    ConnectTypeEnum t = ConnectTypeEnum.ObjOf(confConnect.getTypeId());
                    String sourceConf = t.getUrl().replace("<host>", confConnect.getHost())
                            .replace("<port>", confConnect.getPort()).replace("<db_name>", dbName);
                    return baseMapper.selectTableBySourceAndDbByConfig(sourceConf, params);
                }
            }
            return null;
        } else {
            return null;
        }


    }
    // 获取该数据源，数据库下某个表的字段      表名：字段名
    @Override
    public List<CollectionTableFieldRes> getbloodParameterFiledPlus(Integer id) {
        return baseMapper.selectTableFieldByTableId(id);
    }

    @Override
    public void saveTableDbUsers(List<CollectionTableInfo> tableAdds,
                                 List<CollectionTableInfo> tableUpdates,
                                 List<CollectionTableInfo> tableDeletes,
                                 String dbUserName) {
        Set<Integer> tableIds = Sets.newHashSet();
        for (CollectionTableInfo tableAdd : tableAdds) {
            if (tableAdd.getId() != null) {
                tableIds.add(tableAdd.getId());
            }
        }
        for (CollectionTableInfo tableUpdate : tableUpdates) {
            if (tableUpdate.getId() != null) {
                tableIds.add(tableUpdate.getId());
            }
        }
        if (CollectionUtils.isNotEmpty(tableIds)) {
            baseMapper.batchInsertTableDbUsers(tableIds, dbUserName);
        }
        if (CollectionUtils.isNotEmpty(tableDeletes) && StringUtils.isNotEmpty(dbUserName)) {
            baseMapper.deleteTableDbUsers(tableDeletes, dbUserName);
        }

    }


    /**
     * mysql的模糊查询时特殊字符转义
     */
    private String escapeChar(String before) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(before)) {
            before = before.replaceAll("\\\\", "\\\\\\\\");
            before = before.replaceAll("_", "\\\\_");
            before = before.replaceAll("%", "\\\\%");
            before = before.replaceAll("\\[", "\\\\[");
            before = before.replaceAll("]", "\\\\]");
            before = before.replaceAll("\\^", "\\\\^");
        }
        return before;
    }

    @Override
    public void savePermission(List<CollectionTablePermissionExt> dataList) {
        if (CollectionUtils.isNotEmpty(dataList)) {
            List<SysRoleDataPermission> permissionList = new ArrayList<>(dataList.size());
            for (CollectionTablePermissionExt tableInfoPermission : dataList) {
                SysRoleDataPermission permission = tableInfoPermission.toPermission(tableInfoPermission);
                permissionList.add(permission);
                if (CollectionUtils.isNotEmpty(tableInfoPermission.getCollectionTableFields())) {
                    for (CollectionTableFieldPermission tableFieldInfo : tableInfoPermission.getCollectionTableFields()) {
                        SysRoleDataPermission fieldPermission = tableFieldInfo.toPermission(tableFieldInfo);
                        permissionList.add(fieldPermission);
                    }
                }
            }
            dataPermissionService.savePermission(permissionList);
        }
    }

    @Override
    public void saveMetaPermission(List<CollectionTableInfo> tableAllList, Long initRole, List<CollectionTableInfo> tableDeletes, Long runUser) {
        if (CollectionUtils.isNotEmpty(tableAllList) && initRole != null) {
            //只针对外部元表做权限
            List<CollectionTableInfo> tableAddList = tableAllList.stream().filter(s ->
                    MetaTableTypeEnum.OUT_TABLE.getValue().equals(s.getTableType())).collect(Collectors.toList());
            List<CollectionTablePermissionExt> resultPermissionList = getDataList(initRole, tableAddList,
                    YesOrNoEnum.YES.getValue(), null);
            savePermission(resultPermissionList);
        }
        if (CollectionUtils.isNotEmpty(tableDeletes)) {
            List<Integer> tableDelList = tableDeletes.stream().filter(s ->
                    MetaTableTypeEnum.OUT_TABLE.getValue().equals(s.getTableType()))
                    .map(CollectionTableInfo::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(tableDelList)) {
                sysRoleDataPermissionMapper.delete(new QueryWrapper<SysRoleDataPermission>().eq("data_type"
                        , PermissionTypeEnum.METADATA_MANAGEMENT.getType()).in("data_id", tableDelList)
                );
            }
        }
    }

    @Override
    public void saveCollectionTableCategory(Integer tableId, Long taskId, Integer tenantId, Integer userId) {
        this.baseMapper.saveCollectionTableCategory(tableId,taskId,tenantId,userId);
    }

    @Override
    public PageUtils<CollectionTablePermissionExt> listPageByRole(Map<String, Object> params) {
        if (params.get("role_id") == null || StrUtil.isBlank(params.get("role_id").toString())||Long.valueOf(params.get("role_id").toString()) < 1) {
            return new PageUtils<>(new ArrayList<>(),0,10,1);
        }
        List<CollectionTablePermissionExt> resultPermissionList = new ArrayList<>();
        Long userId = ShiroUtils.getUserId();
        if (!DataPermissionUtil.isAdmin(userId.intValue())) {
            List<Integer> ids = DataPermissionUtil.getDataIds(userId.intValue(),
                    PermissionTypeEnum.METADATA_MANAGEMENT.getType(),
                    PermissionTypeEnum.ASSIGN.getType());
            if (CollectionUtils.isNotEmpty(ids)) {
                params.put("ids", ids);
            } else {
                ids.add(-1);//无权限查询-1的数据
                params.put("ids", ids);
            }
        }
        /*** 查询元数据列表 */
        String tableName = escapeChar(String.valueOf(params.get("tableName")));
        params.put("tableName", tableName);
        Integer tenantId=ShiroUtils.getTenantId();
        if(tenantId!=null){
            params.put("currentTenantId",tenantId);
        }
        if(params.get("cateGoryId")!=null){
            String cateGoryId = (String) params.get("cateGoryId");
            if(StrUtil.isNotBlank(cateGoryId)){
                List<Integer> ids = new ArrayList<>();
                List<Integer> list = this.baseMapper.selectTableIds(Integer.valueOf(cateGoryId));
                if(params.get("ids")!=null){
                    ids = (List<Integer>)params.get("ids");
                    List<Integer> intersection = ids.stream().filter(item -> list.contains(item)).collect(Collectors.toList());
                    if(intersection.size()==0){
                        intersection.add(-1);
                    }
                    params.put("ids", intersection);
                }else {
                    params.put("ids", list);
                }
            }
        }
        IPage<CollectionTableInfo> page = this.baseMapper.listPageByRole((Page<CollectionTableInfo>)
                new Query<CollectionTableInfo>().getPage(params), params);
        List<CollectionTableInfo> records = page.getRecords();
        Long roleId = 0L;
        if (params.get("role_id") != null) {
            roleId = Long.parseLong(params.get("role_id").toString());
        }
        if (CollectionUtils.isNotEmpty(records)) {
            resultPermissionList = getDataList(roleId, records, YesOrNoEnum.NO.getValue(), userId);
        }
        return new PageUtils<>(resultPermissionList,
                (int) page.getTotal(), (int) page.getSize(), (int) page.getCurrent());
    }

    public List<Map<Integer,String>> listUserList(){
        return this.baseMapper.listUserList(ShiroUtils.getTenantId());
    }

    /**
     * 根据角色id 和表数据 查询和生成权限信息
     *
     * @param roleId  角色id
     * @param records 表信息
     * @param userId  执行用户
     */
    private List<CollectionTablePermissionExt> getDataList(Long roleId, List<CollectionTableInfo> records, int yes, Long userId) {

        List<CollectionTablePermissionExt> dataList = new ArrayList<>();
        if (CollectionUtils.isEmpty(records)) {
            return dataList;
        }
        // 查询数据权限信息
        Map<String, SysRoleDataPermission> permissionMap = Maps.newHashMap();
        if (roleId != null) {
            List<Integer> dataTypeList = new ArrayList<>(2);
            dataTypeList.add(PermissionTypeEnum.METADATA_MANAGEMENT.getType());
            dataTypeList.add(PermissionTypeEnum.METADATA_MANAGEMENT_FIELD.getType());
            SysRoleDataPermissionExample param = new SysRoleDataPermissionExample();
            param.createCriteria().andDataTypeIn(dataTypeList)
                    .andRoleIdEqualTo(roleId);
            List<SysRoleDataPermission> list = sysRoleDataPermissionMapper.selectByExample(param);
            if (CollectionUtils.isNotEmpty(list)) {
                for (SysRoleDataPermission sysRoleDataPermission : list) {
                    permissionMap.put(sysRoleDataPermission.getDataId()
                                    + "-" + sysRoleDataPermission.getDataType(),
                            sysRoleDataPermission);
                }
            }
        }
        //查询字段信息
        Set<Integer> tableIds = Sets.newHashSet();
        for (CollectionTableInfo record : records) {
            tableIds.add(record.getId());
        }
        List<CollectionTableField> fieldList = collectionTableFieldMapper.selectListByTableIds(
               tableIds);
        if (userId != null && !DataPermissionUtil.isAdmin(userId.intValue())) {
            //按照权限过滤字段
            List<Integer> ids = DataPermissionUtil.getDataIds(userId.intValue(),
                    PermissionTypeEnum.METADATA_MANAGEMENT_FIELD.getType(), PermissionTypeEnum.ASSIGN.getType());
            fieldList = fieldList.stream().filter(
                    s -> ids.contains(s.getId()) || userId.equals(s.getCreateUser())
            ).collect(Collectors.toList());
        }
        List<CollectionSystemModuleEntity> moduleList = collectionSystemModuleService.list();
        Map<Integer, List<CollectionTableField>> groupByMaps = fieldList.stream()
                .collect(Collectors.groupingBy(CollectionTableField::getTableId));
        for (CollectionTableInfo record : records) {
            String moduleName = ModuleUtils.getAllPath(moduleList, record.getOwnModule());
            record.setModuleName(moduleName);
            List<CollectionTableField> tableFieldList = groupByMaps.get(record.getId());
            List<CollectionTableFieldPermission> tableFieldPerList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(tableFieldList)) {
                for (CollectionTableField tableFieldInfo : tableFieldList) {
                    SysRoleDataPermission permission = permissionMap.get(tableFieldInfo.getId() + "-"
                            + PermissionTypeEnum.METADATA_MANAGEMENT_FIELD.getType());
                    if (permission != null) {
                        CollectionTableFieldPermission tp = new CollectionTableFieldPermission(tableFieldInfo, permission);
                        tableFieldPerList.add(tp);
                    } else {
                        CollectionTableFieldPermission tp = new CollectionTableFieldPermission(tableFieldInfo, null);
                        if (YesOrNoEnum.YES.getValue().equals(yes)) {
                            tp.yesValue(roleId, tableFieldInfo.getId(), PermissionTypeEnum.METADATA_MANAGEMENT_FIELD.getType());
                        } else {
                            tp.defaultValue(roleId, tableFieldInfo.getId(), PermissionTypeEnum.METADATA_MANAGEMENT_FIELD.getType());
                        }
                        tableFieldPerList.add(tp);
                    }
                }
            }
            SysRoleDataPermission permission = permissionMap.get(record.getId() + "-"
                    + PermissionTypeEnum.METADATA_MANAGEMENT.getType());
            if (permission != null) {
                CollectionTablePermissionExt table = new CollectionTablePermissionExt(record, permission);
                List<Integer> categoryIdsList = this.baseMapper.selectCategoryIds(table.getDataId());
                if(categoryIdsList.size()>0){
                    table.setCategoryNamesList(this.baseMapper.selectCategoryNames(categoryIdsList));
                }else {
                    table.setCategoryNamesList(new ArrayList<>());
                }
                table.setCollectionTableFields(tableFieldPerList);
                dataList.add(table);
            } else {
                CollectionTablePermissionExt table = new CollectionTablePermissionExt(record, null);
                List<Integer> categoryIdsList = this.baseMapper.selectCategoryIds(table.getDataId());
                if(categoryIdsList.size()>0){
                    table.setCategoryNamesList(this.baseMapper.selectCategoryNames(categoryIdsList));
                }else {
                    table.setCategoryNamesList(new ArrayList<>());
                }
                table.setCollectionTableFields(tableFieldPerList);
                if (YesOrNoEnum.YES.getValue().equals(yes)) {
                    table.yesValue(roleId, record.getId(), PermissionTypeEnum.METADATA_MANAGEMENT.getType());
                } else {
                    table.defaultValue(roleId, record.getId(), PermissionTypeEnum.METADATA_MANAGEMENT.getType());
                }
                dataList.add(table);
            }
        }
        return dataList;
    }


    // 添加血缘关系
    @Override
    public boolean bloodRelationAdd(AddCollectionRelationDto addCollectionRelationDto) {
        TableRelationshipEntity addTableRelationship = new TableRelationshipEntity();
        boolean flag = false;
        //根据id获取当前表的信息
        CollectionTableInfo collectionTableInfo = baseMapper.selectById(addCollectionRelationDto.getId());
        String currentDbName = collectionTableInfo.getDbName();    // 当前表的数据库名
        String currenTableName = collectionTableInfo.getTableName();   //当前表的表名
        Integer currentSourceId = collectionTableInfo.getSourceId();         // 当前表的数据数据源id
        // 上游表
        if (addCollectionRelationDto.getType().equals(1)) {
            addTableRelationship.setSourceTableName(currenTableName);
            addTableRelationship.setSourceCollTableId(addCollectionRelationDto.getId());
            addTableRelationship.setSourceFieldName(addCollectionRelationDto.getCurrentFiled());
            addTableRelationship.setRelationCollTableId(addCollectionRelationDto.getRelationTableInfoId());
            addTableRelationship.setRelationTableName(addCollectionRelationDto.getRelationTableName());
            addTableRelationship.setRelationDbname(addCollectionRelationDto.getRelationDbName());
            addTableRelationship.setRelationFieldName(addCollectionRelationDto.getRelationFiled());
            addTableRelationship.setRelationSourceId(addCollectionRelationDto.getRelationDataSourceId());
        }
        //下游表
        if (addCollectionRelationDto.getType().equals(0)) {
            addTableRelationship.setSourceTableName(addCollectionRelationDto.getRelationTableName());
            addTableRelationship.setSourceFieldName(addCollectionRelationDto.getRelationFiled());
            addTableRelationship.setSourceCollTableId(addCollectionRelationDto.getRelationTableInfoId());
            addTableRelationship.setRelationCollTableId(addCollectionRelationDto.getId());
            addTableRelationship.setRelationFieldName(addCollectionRelationDto.getCurrentFiled());
            addTableRelationship.setRelationDbname(currentDbName);
            addTableRelationship.setRelationTableName(currenTableName);
            addTableRelationship.setRelationSourceId(currentSourceId);
        }
        if (baseMapper.selectRelationship(addTableRelationship).size() == 0) {
            flag = collectionTableField2Mapper.insertTableRelationship(addTableRelationship);
        }
        return flag;
    }


    // 移除血缘关系
    // @Override
    public boolean removeBloodRelation(List<RelationTable> relationTableList) {
        List<TableRelationshipEntity> tableRelationshipEntityList = new ArrayList<>();


        for (RelationTable relationTable : relationTableList) {
            TableRelationshipEntity tableRelationshipEntity = new TableRelationshipEntity();

            Set<RelationField> fieldList = relationTable.getFieldList();
            List<RelationField> collect = new ArrayList<>(fieldList);

            RelationField relationField = collect.get(0);

            Set<String> toIdList = relationField.getToIdList();

            // 上游连接关系
            if (relationTable.getType().equals(1)) {
                // 如果血缘关系存在则移除
                tableRelationshipEntity.setRelationTableName(relationTable.getTableName());  // 关联数据表名称
                tableRelationshipEntity.setRelationFieldName(relationField.getFileName());   //关联数据字段

                tableRelationshipEntity.setSourceFieldName(relationField.getToFiledName());  //
                tableRelationshipEntity.setSourceTableName(relationField.getToTableName());   //

                if (relationField.getToSourceId() != null) {
                    tableRelationshipEntity.setRelationSourceId(relationField.getToSourceId());  //关联的sourceId
                }

                tableRelationshipEntity.setRelationDbname(relationField.getToDbName());     // 关联的数据库

            }

            // 下游连接关系
            if (relationTable.getType().equals(0)) {
                // 如果血缘关系存在则移除
                tableRelationshipEntity.setSourceTableName(relationTable.getTableName());    // 数据表源名称
                tableRelationshipEntity.setSourceFieldName(relationField.getFileName());     // 数据字段


                tableRelationshipEntity.setSourceFieldName(relationField.getToFiledName());  //
                tableRelationshipEntity.setSourceTableName(relationField.getToTableName());   //

                if (relationField.getToSourceId() != null) {
                    tableRelationshipEntity.setRelationSourceId(relationField.getToSourceId());  //关联的sourceId
                }

                tableRelationshipEntity.setRelationDbname(relationField.getToDbName());     // 关联的数据库

            }

            tableRelationshipEntityList.add(tableRelationshipEntity);

        }


        for (TableRelationshipEntity tableRelationshipEntity : tableRelationshipEntityList) {
            if (baseMapper.selectRelationship(tableRelationshipEntity).size() == 0) {
                throw new RRException("没有找到数据" + tableRelationshipEntity);
            } else {
                baseMapper.deleteRelationship(tableRelationshipEntity);
            }
        }

        return true;

    }

    // 移除血缘关系plus
    @Override
    public boolean removeBloodRelationPlus(RelationTable relationTableList) {
        List<TableRelationshipEntity> tableRelationshipEntityList = new ArrayList<>();


        for (RelationField relationField : relationTableList.getFieldList()) {
            TableRelationshipEntity tableRelationshipEntity = new TableRelationshipEntity();

            // 上游连接关系
            if (relationTableList.getType().equals(1)) {
                // 如果血缘关系存在则移除
                tableRelationshipEntity.setRelationTableName(relationTableList.getTableName());  // 关联数据表名称
                tableRelationshipEntity.setRelationFieldName(relationField.getFileName());   //关联数据字段

                tableRelationshipEntity.setSourceFieldName(relationField.getToFiledName());  //
                tableRelationshipEntity.setSourceTableName(relationField.getToTableName());   //

                if (relationField.getToSourceId() != null) {
                    tableRelationshipEntity.setRelationSourceId(relationField.getToSourceId());  //关联的sourceId
                }

                tableRelationshipEntity.setRelationDbname(relationField.getToDbName());     // 关联的数据库

            }

            // 下游连接关系
            if (relationTableList.getType().equals(0)) {
                // 如果血缘关系存在则移除
                tableRelationshipEntity.setSourceTableName(relationTableList.getTableName());    // 数据表源名称
                tableRelationshipEntity.setSourceFieldName(relationField.getFileName());     // 数据字段


                tableRelationshipEntity.setRelationFieldName(relationField.getToFiledName());  //
                tableRelationshipEntity.setRelationTableName(relationField.getToTableName());   //

                if (relationField.getToSourceId() != null) {
                    tableRelationshipEntity.setRelationSourceId(relationField.getToSourceId());  //关联的sourceId
                }

                tableRelationshipEntity.setRelationDbname(relationField.getToDbName());     // 关联的数据库

            }

            tableRelationshipEntityList.add(tableRelationshipEntity);

        }


        for (TableRelationshipEntity tableRelationshipEntity : tableRelationshipEntityList) {
            if (baseMapper.selectRelationship(tableRelationshipEntity).size() == 0) {
                throw new RRException("没有找到数据" + tableRelationshipEntity);
            } else {
                baseMapper.deleteRelationship(tableRelationshipEntity);
            }
        }

        return true;

    }


}

